package trimble

import (
	"dgo/goutils/utils"
)

var (
	bd970_start_buf        = []byte{0x02}
	bd970_max_len   uint16 = 10240
)

type TrimbleDecoder struct {
	decodeStep int8
	bodyl      uint16
	cache      utils.BytesBuilder

	PackageType byte

	RecordType                byte
	PageTotal                 byte
	PageCurrent               byte
	ReplyNumber               byte
	RecordInterpretationFlags byte

	Pages utils.BytesBuilder

	/**
	  packBuf 整个包的Buf
	*/
	OnPackage func(packet_type byte, packbuf []byte)
}

func NewTrimbleDecoder() *TrimbleDecoder {
	rval := &TrimbleDecoder{}
	return rval
}

func (this *TrimbleDecoder) PackageBuf() []byte {
	return this.cache.Bytes()
}

func (this *TrimbleDecoder) GetBody() []byte {
	return this.cache.Buff(8, int(this.bodyl)-4)
}

func (this *TrimbleDecoder) IsPageOver() bool {
	return this.PageTotal == this.PageCurrent
}

func (this *TrimbleDecoder) CHECKSUM_Over() bool {
	checksum, result := this.CHECKSUM_ret()
	return checksum == result

}

func (this *TrimbleDecoder) CHECKSUM_ret() (checksum byte, result byte) {

	checksum = 0 //status+Ptype+length+数据流值累加器A
	for ix := 1; ix < this.cache.Len()-2; ix++ {
		//fmt.Println(this.cache.Byte(ix))
		checksum += this.cache.Byte(ix)
	}

	result = this.cache.Byte(this.cache.Len() - 2)
	return
}

func (this *TrimbleDecoder) InputByte(v byte) int {
	if this.decodeStep <= 0 {
		this.cache.Reset()
		this.decodeStep = 1
		//this.A = 0
	}

	this.cache.WriteByte(v)

	l := this.cache.Len()

	//this.Add_A(v)

	if this.decodeStep == 1 {
		if l <= len(bd970_start_buf) {
			idx := l - 1
			if this.cache.Byte(idx) != bd970_start_buf[idx] {
				this.decodeStep = -1
				return -1
			}
			return 0
		} else if l == 3 { // 响应包的类型
			ptype := this.cache.Byte(2)
			if ptype != 0x57 {
				this.decodeStep = -1
				return -1
			}
			this.PackageType = ptype
		} else if l == 4 { // 长度
			this.bodyl = uint16(this.cache.Byte(3))
			if this.bodyl > bd970_max_len {
				this.decodeStep = -1
				return -1
			}
			this.decodeStep = 2 // 解码Header
		}
	} else if this.decodeStep == 2 {
		if l == 8 {
			this.RecordType = this.cache.Byte(4)

			v := this.cache.Byte(5)
			this.PageTotal = v & 0x0F
			this.PageCurrent = v >> 4

			if this.PageCurrent == 1 {
				this.ReplyNumber = this.cache.Byte(6)
			} else {
				if this.ReplyNumber != this.cache.Byte(6) {
					this.decodeStep = -1
					return -1
				}
			}

			this.RecordInterpretationFlags = this.cache.Byte(7)

			this.decodeStep = 3
		}
	} else if this.decodeStep == 3 {
		if l == 3+int(this.bodyl)+3 {
			if this.cache.Byte(l-1) != 0x03 {
				return -1
			}
			if this.OnPackage != nil {
				this.OnPackage(this.PackageType, this.cache.Bytes())
			}
			this.decodeStep = 0
			return 1
		}

	}

	return 0
}

func (this *TrimbleDecoder) InputBuf(buf []byte) {
	for i := 0; i < len(buf); i++ {
		this.InputByte(buf[i])
	}

}
